package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/requestid"
	"github.com/gofiber/websocket/v2"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"qiuqiu.top/my-api/model"
	"time"
)

// 初始化数据库连接
func InitDB() (*gorm.DB, error) {
	db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{
		// 开启 WAL 模式
		//DSN: "mode=wal",
		// 增加最大连接数为 100
		//MaxOpenConns: 100,
	})
	if err != nil {
		return nil, err
	}
	// 设置数据库连接池参数
	sqlDB, err := db.DB()
	if err != nil {
		return nil, err
	}
	sqlDB.SetMaxIdleConns(10)
	sqlDB.SetMaxOpenConns(100)
	sqlDB.SetConnMaxLifetime(time.Hour)

	return db, nil
}

// 定义批量写入函数
func BatchInsertUsers(db *gorm.DB, users []model.User) error {
	// 每次写入 1000 条数据
	batchSize := 1
	batchCount := (len(users) + batchSize - 1) / batchSize
	for i := 0; i < batchCount; i++ {
		start := i * batchSize
		end := (i + 1) * batchSize
		if end > len(users) {
			end = len(users)
		}
		batch := users[start:end]
		// 启用事务
		tx := db.Begin()
		if err := tx.Error; err != nil {
			return err
		}
		if err := tx.Create(&batch).Error; err != nil {
			tx.Rollback()
			return err
		}
		// 提交事务
		if err := tx.Commit().Error; err != nil {
			return err
		}
	}
	return nil
}

// 查询用户信息
func GetUsers(db *gorm.DB) ([]*model.User, error) {
	var users []*model.User
	// 使用缓存，减少对数据库的读操作
	err := db.Find(&users).Error
	if err != nil {
		return nil, err
	}
	return users, nil
}

var forwardWs *websocket.Conn
var mt1 int

type ForwardItem struct {
	Proxy          string            `json:"proxy,omitempty"`
	Method         string            `json:"method,omitempty"`
	Headers        map[string]string `json:"headers,omitempty"`
	Url            string            `json:"url,omitempty"`
	Data           string            `json:"data,omitempty"`
	Timeout        int               `json:"timeout,omitempty"`
	AllowRedirects bool              `json:"allow_redirects,omitempty"`
	Verify         bool              `json:"verify,omitempty"`
	Debug          bool              `json:"debug"`
	Id             string            `json:"id"`
}

var respChan chan *forawrdInfo

type forawrdInfo struct {
	id   string `json:"id"`
	resp string `json:"resp"`
}

// 示例代码
func main() {
	respChan = make(chan *forawrdInfo, 10)
	// 批量插入数据
	model.Init()
	app := fiber.New()

	app.Use(requestid.New())
	app.Get("/ws", websocket.New(func(c *websocket.Conn) {
		forwardWs = c
		for {
			// Read
			mt, msg, err := c.ReadMessage()
			mt1 = mt
			if err != nil {
				println("read:", err.Error())
				break
			}
			v := make(map[string]string)
			err = json.Unmarshal(msg, &v)
			if err != nil {
				fmt.Println(err.Error())
			}
			fmt.Println("recv: ", v["id"])

			// Write
			if v["id"] != "" {
				respChan <- &forawrdInfo{id: v["id"], resp: v["resp"]}
			} else {
				//err = c.WriteMessage(mt, []byte("{\"url\":\"https://collector-pxvb73hteg.px-cloud.net/assets/js/bundle\",\"headers\":{\"accept\":\"*/*\",\"accept-language\":\"en\",\"cache-control\":\"no-cache\",\"content-type\":\"application/x-www-form-urlencoded\",\"pragma\":\"no-cache\",\"sec-ch-ua-mobile\":\"?1\",\"sec-fetch-dest\":\"empty\",\"sec-fetch-mode\":\"cors\",\"sec-fetch-site\":\"cross-site\"},\"data\":\"payload=aUkQRhAIEGJqAwACCwcQHhBWEAhJEGJqAwMEBgcQCBBaRkZCQQgdHVBdXVlbXFUcVF5LVEBdXEZbV0AcUV1fHXReW1VaRh1hV15XUUYQHhBiagMAAAIFEAgCHhBiagMABgcKEAgQf1NRe1xGV14QHhBiagMDCgsKEAhGQEdXHhBiagMDCwIAEAgCHhBiagMDBwQCEAgDAwcBHhBiagMAAAYKEAgBBAIGCHh^BiagMDAQoHEAgDSBQIAAgACBwQHAQoHHh}BiaDgMAAAoCEAgDBQIAAgACBwQHAQsNBHhKBia8gMDDBgsNEEAgQBlNXVa>goHU1MfCwcLUB8DA1dXHwtWVwMfVwAFVwQKAwDELA`gQKKEB4QYmoDAAcEBh}AIXEdeXh4QYGmoDAAcEBxAIHwMeEGJqAwMBBQsKQCFRTXkFXHhBiagMAA7QIFEAgQYmoDAwUGBxAeEGJqAwMEBAoQCBBCSlpREB4QYmo7DAAEGChAIVFNeQVdPT28=&appId=PXVb73hTEg&tag=v8.7.2&uuid=4aed85aa-959b-11ee-9de1-e27e68139068&ft=317&seq=0&en=NTA&pc=2921655305870709&sid=67f99d4e-959b-11ee-9725-1b5b27cc2bc7&vid=67f993ec-959b-11ee-9725-35399a5f1c59&cts=67f9a092-959b-11ee-9725-1b5b27cc2bc7&rsc=1\",\"method\":\"POST\"}"))
				err = c.WriteMessage(mt, []byte("{\"status\":0}"))
				if err != nil {
					println("write:", err.Error())
					break
				}
			}

		}

	}))
	app.Post("/tls/forward", func(ctx *fiber.Ctx) error {
		println(string(ctx.Body()))
		item := &ForwardItem{}
		json.Unmarshal(ctx.Body(), item)
		//item.id = uuid.New().String()
		fmt.Println("发送id", item.Id)

		if forwardWs != nil {
			//body, _ := json.Marshal(item)
			err := forwardWs.WriteMessage(mt1, ctx.Body())
			if err != nil {
				fmt.Println(err.Error())
				return err
			}
			for {
				r := <-respChan
				fmt.Println("rrr", r.id)
				if r.id == item.Id {
					res1, _ := base64.StdEncoding.DecodeString(r.resp)
					res := map[string]interface{}{
						"text":    string(res1),
						"cookies": map[string]string{},
					}
					marshal, err := json.Marshal(&res)
					if err != nil {
						return err
					}
					ctx.Write(marshal)
					break

				}

			}
		}
		return nil

	})
	app.Listen(":3000")

}
